home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / vt220fontedit < prev    next >
Encoding:
Internet Message Format  |  1988-01-31  |  24.1 KB

  1. Subject:  v13i076:  Font edit program for VT220 terminals
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: "Eric A. Pearce" <eap@bucsf.bu.edu>
  7. Posting-number: Volume 13, Issue 76
  8. Archive-name: vt220fontedit
  9.  
  10.  
  11. This screen-oriented program lets you edit downloaded fonts for the VT220
  12. terminal.  This version runs on SysV and BSD.
  13.                              - Eric Pearce, Boston University
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of shell archive."
  22. # Contents:  README Makefile fontedit.1 fontedit.c
  23.  
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f README -a "${1}" != "-c" ; then 
  26.   echo shar: Will not over-write existing file \"README\"
  27. else
  28. echo shar: Extracting \"README\" \(1482 characters\)
  29. sed "s/^X//" >README <<'END_OF_README'
  30. XWhen I first saw this posted to rn, I tried to compile this on a machine 
  31. Xrunning BSD UNIX.  Much to my dissapointment, It said "unable to find
  32. X/usr/include/termio.h" and thus it sat for a couple months.  I was able to
  33. Xcompile it on a 3b5, but I didn't have a vt220 hooked up to it.  I was doing
  34. Xsome unrelated work with ioctl calls and finally realized that it would not be
  35. Xtoo hard to convert it from System V to BSD.  It also looked kind of strange
  36. Xwith the cursor on, so I turned this off.  To implement this, compile with
  37. Xthe "-DCURFIX" flag in the Makefile.  
  38. XI am working on a new version that uses curses and that would enable you to 
  39. Xchange the file that your are working on without leaving the program.  
  40. XI thought I'd post it as it is now, since it has a lot of uses right away.
  41. XImagine changing your favorite game to have objects that look like what they 
  42. Xare instead of the regular characters.  Also, I think people should post their
  43. Xown character sets, if they come up with some neat stuff. 
  44. X             Please send any comments or suggestions to:
  45. X                                                  
  46. X                 UUCP   : ..!harvard!bu-cs!bucsb!eap
  47. X                 ARPANET: eap@bucsb.bu.edu  
  48. X                 CSNET  : eap%bucsb@bu-cs   
  49. X                                        
  50. X                                       Have fun,
  51. X
  52. X                                            - Eric Pearce
  53. X                                              Boston University
  54. X
  55. X
  56. X
  57. X
  58. X
  59. X
  60. X
  61. X
  62. X
  63. X
  64. X
  65. X
  66. END_OF_README
  67. if test 1482 -ne `wc -c <README`; then
  68.     echo shar: \"README\" unpacked with wrong size!
  69. fi
  70. # end of overwriting check
  71. fi
  72. if test -f Makefile -a "${1}" != "-c" ; then 
  73.   echo shar: Will not over-write existing file \"Makefile\"
  74. else
  75. echo shar: Extracting \"Makefile\" \(222 characters\)
  76. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  77. X# BSD   (new version, uses Berkeley specific ioctl calls) 
  78. X# SYSV  (old version, uses System V specific ioctl calls)
  79. X# CURFIX (turn off cursor on display)
  80. Xfontedit : fontedit.c
  81. X    cc fontedit.c -O -o fontedit -DBSD -DCURFIX
  82. END_OF_Makefile
  83. if test 222 -ne `wc -c <Makefile`; then
  84.     echo shar: \"Makefile\" unpacked with wrong size!
  85. fi
  86. # end of overwriting check
  87. fi
  88. if test -f fontedit.1 -a "${1}" != "-c" ; then 
  89.   echo shar: Will not over-write existing file \"fontedit.1\"
  90. else
  91. echo shar: Extracting \"fontedit.1\" \(1927 characters\)
  92. sed "s/^X//" >fontedit.1 <<'END_OF_fontedit.1'
  93. X.TH FONTEDIT 1 LOCAL
  94. X.SH NAME
  95. Xfontedit \- Edit fonts.
  96. X.SH SYNOPSIS
  97. X.B fontedit file
  98. X.SH DESCRIPTION
  99. X.I Fontedit
  100. Xis used to edit the down line reloadable character set (DRCS) of a VT220
  101. Xterminal.  The editor has two display areas, one for displaying the
  102. Xentry currently being manipulated, and one for displaying the complete
  103. XDRCS.  Commands to the editor take the form of function keys.
  104. X.PP
  105. X.I Fontedit 
  106. Xtakes one command line parameter, a file name.  This file is
  107. Xused to save the character set.  If the file exists when \fIfontedit\fP
  108. Xis invoked, it is read in to initialize the DRCS.  The file is written
  109. Xto when \fIfontedit\fP exits.
  110. X.PP
  111. XCommands to fontedit take the form of function keys.  The current
  112. Xdefinitions are:
  113. X.IP \fBHELP\fP
  114. XDisplay a help screen.
  115. X.IP \fBF6\fP
  116. XTurn the pixel under the cursor on.
  117. X.IP \fBF7\fP
  118. XTurn the pixel under the cursor off.
  119. X.IP \fBF13\fP
  120. XClear the display area.
  121. X.IP \fBFind\fP
  122. XSave the current font in the font table.  Update the DRCS display.
  123. X.IP \fBSelect\fP
  124. XExtract the entry selected by the cursor in the DRCS display.
  125. X.IP \fBPrev\fP
  126. XMove the cursor to the previous entry in the DRCS display.
  127. X.IP \fBNext\fP
  128. XMove the cursor to the next entry in the DRCS display.
  129. X.IP \fBInsert\fP
  130. XInsert a blank line at the current cursor position.  The bottom row is lost.
  131. X.IP \fBRemove\fP
  132. XRemove the row at the current cursor position.  All rows below the
  133. Xcurrent one are shifted up.
  134. X.IP \fBCursors\fP
  135. XMove the cursor in the main display area.
  136. X.PP
  137. XIf the screen gets garbled, press <control-L>.
  138. X.PP
  139. XTo exit \fIfontedit\fP, press <control-D>.  The DRCS will be saved in
  140. X\fIfile\fP.  To exit without saving the DRCS, hit interrupt (usually
  141. XDEL). 
  142. X.SH DIAGNOSTICS
  143. X.I Fontedit
  144. Xwill issue a warning when the entry being worked on is not saved, and
  145. Xsome potentially destructive command, like \fBSelect\fP is used.  To
  146. Xoverride the warning message, immediately reissue the command.
  147. X.SH AUTHOR
  148. XGreg Franks.
  149. X
  150. X
  151. END_OF_fontedit.1
  152. if test 1927 -ne `wc -c <fontedit.1`; then
  153.     echo shar: \"fontedit.1\" unpacked with wrong size!
  154. fi
  155. # end of overwriting check
  156. fi
  157. if test -f fontedit.c -a "${1}" != "-c" ; then 
  158.   echo shar: Will not over-write existing file \"fontedit.c\"
  159. else
  160. echo shar: Extracting \"fontedit.c\" \(17714 characters\)
  161. sed "s/^X//" >fontedit.c <<'END_OF_fontedit.c'
  162. X/*
  163. X * fontedit
  164. X *    Fonteditor for VT220
  165. X *
  166. X *  BUGS:
  167. X *    o Cursor motion is less than optimal (but who cares at 9600),
  168. X *
  169. X *  COMPILE:
  170. X *    cc -O fontedit.c -o fontedit
  171. X *      (use Makefile)
  172. X *
  173. X *    Copyright (c) 1987 by Greg Franks.
  174. X *
  175. X *    Permission is granted to do anything you want with this program
  176. X *    except claim that you wrote it.
  177. X *
  178. X *
  179. X *      REVISION HISTORY:
  180. X *
  181. X *      Nov 21, 1987 - Fixed man page to say "Fontedit" instead of "Top" 
  182. X *      Nov 22, 1987 - Added BSD Compatible ioctl, turned cursor on/off
  183. X *                     - eap@bucsf.bu.edu
  184. X */
  185. X
  186. X#include <stdio.h>
  187. X#ifdef SYSV
  188. X#include <sys/termio.h>
  189. X#endif SYSV
  190. X#ifdef BSD
  191. X#include <sys/ioctl.h>
  192. X#endif BSD
  193. X#include <signal.h>
  194. X
  195. X#ifdef CURFIX
  196. X#define CURSORON  "\033[?25h"
  197. X#define CURSOROFF "\033[?25l"
  198. X#endif CURFIX
  199. X
  200. X#define    MAX_ROWS    10
  201. X#define    MAX_COLS    8
  202. X
  203. Xtypedef enum { false, true } bool;
  204. X
  205. X#define    KEY_FIND     0x0100
  206. X#define    KEY_INSERT     0x0101
  207. X#define    KEY_REMOVE     0x0102
  208. X#define    KEY_SELECT     0x0103
  209. X#define    KEY_PREV     0x0104
  210. X#define    KEY_NEXT     0x0105
  211. X#define    KEY_F6        0X0106
  212. X#define    KEY_F7        0x0107
  213. X#define    KEY_F8        0x0108
  214. X#define    KEY_F9        0x0109
  215. X#define    KEY_F10        0x010a
  216. X#define    KEY_F11        0x010b
  217. X#define    KEY_F12        0x010c
  218. X#define    KEY_F13        0x010d
  219. X#define    KEY_F14        0x010e
  220. X#define    KEY_HELP    0x010f
  221. X#define    KEY_DO        0x0110
  222. X#define    KEY_F17        0x0111
  223. X#define    KEY_F18        0x0112
  224. X#define    KEY_F19        0x0113
  225. X#define    KEY_F20        0x0114
  226. X#define    KEY_UP         0x0115
  227. X#define    KEY_DOWN     0x0116
  228. X#define    KEY_RIGHT     0x0117
  229. X#define    KEY_LEFT     0x0118
  230. X
  231. X/*
  232. X * Position of main drawing screen.
  233. X */
  234. X
  235. X#define    ROW_OFFSET    3
  236. X#define COL_OFFSET    10
  237. X
  238. X/* 
  239. X * Position of the DRCS table.
  240. X */
  241. X
  242. X#define    TABLE_ROW    4
  243. X#define    TABLE_COL    50
  244. X
  245. X/*
  246. X *
  247. X */
  248. X
  249. X#define    ERROR_ROW    20
  250. X#define ERROR_COL    40
  251. X
  252. Xbool    display_table[MAX_ROWS][MAX_COLS];
  253. X
  254. X#define    TOTAL_ENTRIES    (128 - 32)
  255. X#define    SIXELS_PER_CHAR    16
  256. X
  257. Xchar    font_table[TOTAL_ENTRIES][SIXELS_PER_CHAR];
  258. Xunsigned int    current_entry;
  259. X
  260. X#ifdef SYSV
  261. Xstruct termio old_stty, new_stty;
  262. X#endif SYSV
  263. X#ifdef BSD
  264. Xstruct sgttyb old_stty, new_stty;
  265. X#endif BSD
  266. X
  267. XFILE * font_file = (FILE *)0;
  268. X
  269. X
  270. X/*
  271. X * Interrupt
  272. X *    Exit gracefully.
  273. X */
  274. X
  275. Xinterrupt()
  276. X{
  277. X    void clear_screen();
  278. X#ifdef CURFIX
  279. X        printf("%s\n",CURSORON);   
  280. X#endif CURFIX   
  281. X#ifdef SYSV
  282. X    ioctl( 0, TCSETA, &old_stty );
  283. X#endif SYSV
  284. X#ifdef BSD
  285. X        ioctl( 0, TIOCSETP, &old_stty );
  286. X#endif BSD
  287. X    clear_screen();
  288. X    exit( 0 );
  289. X}
  290. X
  291. X
  292. X/*
  293. X * Main
  294. X *    Grab input/output file and call main command processor.
  295. X */
  296. X    
  297. Xmain( argc, argv )
  298. Xint argc;
  299. Xchar *argv[];
  300. X{
  301. X    void command(), init_restore(), clear_screen();
  302. X    void save_table(), get_table(), extract_entry();
  303. X
  304. X    if ( argc != 2 ) {
  305. X        fprintf( stderr, "useage: fontedit filename\n" );
  306. X        exit( 1 );
  307. X    }
  308. X
  309. X    printf( "Press HELP for help\n" );
  310. X    printf( "\033P1;1;2{ @\033\\" );    /* Clear font buffer    */
  311. X    fflush( stdout );
  312. X    sleep( 1 );            /* Let terminal catch up    */
  313. X                    /* otherwise we get frogs    */
  314. X
  315. X    if ( ( font_file = fopen( argv[1], "r" ) ) != (FILE *)0 ) {
  316. X        get_table( font_file );
  317. X        fclose( font_file );
  318. X    }
  319. X
  320. X    if ( ( font_file = fopen( argv[1], "r+" ) ) == (FILE *)0 ) {
  321. X        fprintf( stderr, "Cannot open %s for writing\n", argv[1] );
  322. X        exit( 1 );
  323. X    }
  324. X#ifdef CURFIX
  325. X        printf("%s\n",CURSOROFF);
  326. X#endif CURFIX
  327. X#ifdef SYSV
  328. X    ioctl( 0, TCGETA, &old_stty );
  329. X#endif SYSV
  330. X#ifdef BSD
  331. X        ioctl( 0, TIOCGETP, &old_stty );
  332. X#endif BSD
  333. X    signal( SIGINT, interrupt );
  334. X
  335. X    new_stty = old_stty;
  336. X#ifdef SYSV
  337. X    new_stty.c_lflag &= ~ICANON;
  338. X    new_stty.c_cc[VMIN] = 1;
  339. X    ioctl( 0, TCSETA, &new_stty );
  340. X#endif SYSV
  341. X#ifdef BSD
  342. X    new_stty.sg_flags |= CBREAK;               
  343. X        new_stty.sg_flags &= ~ECHO;
  344. X    ioctl( 0, TIOCSETP, &new_stty );
  345. X#endif BSD
  346. X    current_entry = 1;
  347. X    extract_entry( current_entry );
  348. X    init_restore();
  349. X    command();
  350. X#ifdef SYSV
  351. X    ioctl( 0, TCSETA, &old_stty );
  352. X#endif SYSV
  353. X#ifdef BSD
  354. X    ioctl( 0, TIOCSETP, &old_stty );
  355. X#endif BSD
  356. X    clear_screen();
  357. X
  358. X    /* Overwrite the old file. */
  359. X
  360. X    fseek( font_file, 0L, 0 );
  361. X    save_table( font_file );
  362. X    fclose( font_file );
  363. X#ifdef CURFIX
  364. X        printf("%s\n",CURSORON);
  365. X#endif CURFIX
  366. X}
  367. X
  368. X
  369. X
  370. X/*
  371. X * Command
  372. X *    Process a function key. 
  373. X *
  374. X *    The user cannot fill in slots 0 or 95 (space and del respecitively).
  375. X */
  376. X
  377. Xvoid
  378. Xcommand()
  379. X{
  380. X    register int c;
  381. X    register int row, col;
  382. X    register int i, j;
  383. X    bool change, error, override;
  384. X
  385. X    void build_entry(), extract_entry(), send_entry(), print_entry();
  386. X    void highlight(), draw_current(), init_restore(), help();
  387. X    void warning();
  388. X
  389. X    change = false;
  390. X    error = false;
  391. X    override = false;
  392. X    row = 0; col = 0;
  393. X    highlight( row, col, true );
  394. X
  395. X    for ( ;; ) {
  396. X        c = get_key();
  397. X        highlight( row, col, false );    /* turn cursor off    */
  398. X
  399. X        if ( error ) {
  400. X            move ( ERROR_ROW, ERROR_COL );
  401. X            printf( "\033[K" );        /* Clear error message    */
  402. X            move ( ERROR_ROW+1, ERROR_COL );
  403. X            printf( "\033[K" );        /* Clear error message    */
  404. X            error = false;
  405. X        } else {
  406. X            override = false;
  407. X        }
  408. X
  409. X        switch ( c ) {
  410. X
  411. X        case KEY_FIND:        /* update DRCS     */
  412. X            if ( !change && !override ) {
  413. X                warning( "No changes to save" );
  414. X                override = true;
  415. X                error = true;
  416. X            } else {
  417. X                build_entry( current_entry );
  418. X                send_entry( current_entry );
  419. X                print_entry( current_entry, true );
  420. X                change = false;
  421. X            }
  422. X            break;
  423. X
  424. X        case KEY_F6:        /* Turn on pixel    */
  425. X            change = true;
  426. X            display_table[row][col] = true;
  427. X            highlight( row, col, false );
  428. X            col = ( col + 1 ) % MAX_COLS;
  429. X            if ( col == 0 )
  430. X                row = ( row + 1 ) % MAX_ROWS;
  431. X            break;
  432. X
  433. X        case KEY_F7:        /* Turn off pixel    */
  434. X            change = true;
  435. X            display_table[row][col] = false;
  436. X            highlight( row, col, false );
  437. X            col = ( col + 1 ) % MAX_COLS;
  438. X            if ( col == 0 )
  439. X                row = ( row + 1 ) % MAX_ROWS;
  440. X            break;
  441. X
  442. X        case KEY_INSERT:    /* Insert a blank row    */
  443. X            change = true;
  444. X            for ( j = 0; j < MAX_COLS; ++j ) {
  445. X                for ( i = MAX_ROWS - 1; i > row; --i ) {
  446. X                    display_table[i][j] = display_table[i-1][j];
  447. X                }
  448. X                display_table[row][j] = false;
  449. X            }
  450. X            draw_current();
  451. X            break;
  452. X    
  453. X        case KEY_REMOVE:    /* Remove a row    */
  454. X            change = true;
  455. X            for ( j = 0; j < MAX_COLS; ++j ) {
  456. X                for ( i = row; i < MAX_ROWS - 1; ++i ) {
  457. X                    display_table[i][j] = display_table[i+1][j];
  458. X                }
  459. X                display_table[MAX_ROWS-1][j] = false;
  460. X            }
  461. X            draw_current();
  462. X            break;
  463. X
  464. X        case KEY_F13:        /* Clear buffer    */
  465. X            if ( change && !override ) {
  466. X                warning( "Changes not saved" );
  467. X                error = true;
  468. X                override = true;
  469. X            } else {
  470. X                for ( j = 0; j < MAX_COLS; ++j ) {
  471. X                    for ( i = 0; i < MAX_ROWS; ++i ) {
  472. X                        display_table[i][j] = false;
  473. X                    }
  474. X                }
  475. X                draw_current();
  476. X            }
  477. X            break;
  478. X
  479. X        case KEY_SELECT:    /* Select font from DRCS    */
  480. X            if ( change && !override ) {
  481. X                warning( "Changes not saved" );
  482. X                error = true;
  483. X                override = true;
  484. X            } else { 
  485. X                extract_entry( current_entry );
  486. X                draw_current();
  487. X            }
  488. X            break;
  489. X
  490. X        case KEY_PREV:        /* Move to prev entry in DRCS    */
  491. X            if ( change && !override ) {
  492. X                warning( "Changes not saved" );
  493. X                override = true;
  494. X                error = true;
  495. X            } else {
  496. X                print_entry( current_entry, false );
  497. X                current_entry = current_entry - 1;
  498. X                if ( current_entry == 0 ) 
  499. X                    current_entry = TOTAL_ENTRIES - 2;
  500. X                print_entry( current_entry, true );
  501. X            }
  502. X            break;
  503. X
  504. X        case KEY_NEXT:        /* Move to next entry in DRCS    */
  505. X            if ( change && !override ) {
  506. X                warning( "Changes not saved" );
  507. X                override = true;
  508. X                error = true;
  509. X            } else {
  510. X                print_entry( current_entry, false );
  511. X                current_entry = current_entry + 1;
  512. X                if ( current_entry  == TOTAL_ENTRIES - 1 )
  513. X                    current_entry = 1;
  514. X                print_entry( current_entry, true );
  515. X            }
  516. X            break;
  517. X
  518. X        case KEY_UP:        /* UP one row.            */
  519. X            if ( row == 0 )
  520. X                row = MAX_ROWS;
  521. X            row = row - 1;
  522. X            break;
  523. X
  524. X        case KEY_DOWN:        /* Guess.            */
  525. X            row = ( row + 1 ) % MAX_ROWS;
  526. X            break;
  527. X
  528. X        case KEY_RIGHT:
  529. X            col = ( col + 1 ) % MAX_COLS;
  530. X            break;
  531. X
  532. X        case KEY_LEFT:
  533. X            if ( col == 0 ) 
  534. X                col = MAX_COLS;
  535. X            col = col - 1;
  536. X            break;
  537. X
  538. X        case KEY_HELP:        /* Display helpful info        */
  539. X            clear_screen();
  540. X            help();
  541. X            c = getchar();
  542. X            init_restore();
  543. X            break;
  544. X
  545. X        case '\004':        /* All done!            */
  546. X            return;
  547. X
  548. X        case '\f':        /* Redraw display        */
  549. X            init_restore();
  550. X            break;
  551. X
  552. X        default:        /* user is a klutzy  typist    */
  553. X            move ( ERROR_ROW, ERROR_COL );
  554. X            printf( "Unknown key: " );
  555. X            if ( c < 0x20 ) {
  556. X                printf( "^%c", c );
  557. X            } else if ( c < 0x0100 ) {
  558. X                printf( "%c", c );
  559. X            } else {
  560. X                printf( "0x%04x", c );
  561. X            }
  562. X            fflush( stdout );
  563. X            error = true;
  564. X        }
  565. X
  566. X        highlight( row, col, true );    /* turn cursor on    */
  567. X    }
  568. X}
  569. X
  570. X
  571. X
  572. Xchar *key_table[]    = {
  573. X    "\033[1~",        /* Find        */
  574. X    "\033[2~",        /* Insert    */
  575. X    "\033[3~",        /* Remove    */
  576. X    "\033[4~",        /* Select    */
  577. X    "\033[5~",        /* Prev        */
  578. X    "\033[6~",        /* Next        */
  579. X    "\033[17~",
  580. X    "\033[18~",
  581. X    "\033[19~",
  582. X    "\033[20~",
  583. X    "\033[21~",
  584. X    "\033[23~",
  585. X    "\033[24~",
  586. X    "\033[25~",
  587. X    "\033[26~",
  588. X    "\033[28~",
  589. X    "\033[29~",
  590. X    "\033[31~",
  591. X    "\033[32~",
  592. X    "\033[33~",
  593. X    "\033[34~",
  594. X    "\033[A",
  595. X    "\033[B",
  596. X    "\033[C",
  597. X    "\033[D",
  598. X    (char *)0 };
  599. X
  600. X/*
  601. X * get_key
  602. X *    Convert VT220 escape sequence into something more reasonable.
  603. X */
  604. X
  605. Xint
  606. Xget_key()
  607. X{
  608. X    register char    *p;
  609. X    char    s[10];
  610. X    register int i, j;
  611. X
  612. X    p = s;
  613. X    for ( i = 0; i < 10; ++i ) {
  614. X        *p = getchar();
  615. X        if ( i == 0 && *p != '\033' )
  616. X            return( (int)*p );    /* Not an escape sequence */
  617. X        if ( *p != '\033' && *p < 0x0020 )
  618. X            return( (int)*p );    /* Control character    */
  619. X        *++p = '\0';            /* Null terminate    */
  620. X        for ( j = 0; key_table[j]; ++j ) {
  621. X            if ( strcmp( s, key_table[j] ) == 0 )
  622. X                return( j | 0x0100 );
  623. X        }
  624. X    }
  625. X    return( -1 );
  626. X}
  627. X
  628. X
  629. X
  630. X/*
  631. X * pad
  632. X *    Emit nulls so that the terminal can catch up.
  633. X */
  634. X
  635. Xpad()
  636. X{
  637. X    int i;
  638. X
  639. X    for ( i = 0; i < 20; ++i )
  640. X        putchar( '\000' );
  641. X    fflush( stdout );
  642. X}
  643. X
  644. X
  645. X
  646. X/*
  647. X * init_restore
  648. X *    refresh the main display table.
  649. X */
  650. X
  651. Xvoid
  652. Xinit_restore()
  653. X{
  654. X    register int row, col;
  655. X    register int i;
  656. X    
  657. X    void  draw_current(), clear_screen(), print_entry();
  658. X
  659. X    clear_screen();
  660. X
  661. X    for ( col = 0; col < MAX_COLS; ++col ) {
  662. X        move( ROW_OFFSET - 2, col * 3 + COL_OFFSET + 1 );
  663. X        printf( "%d", col );
  664. X    }
  665. X    move( ROW_OFFSET - 1, COL_OFFSET );
  666. X    printf( "+--+--+--+--+--+--+--+--+" );
  667. X    move( ROW_OFFSET + MAX_ROWS * 2, COL_OFFSET );
  668. X    printf( "+--+--+--+--+--+--+--+--+" );
  669. X
  670. X    for ( row = 0; row < MAX_ROWS; ++row ) {
  671. X        if ( row != 0 && row != 7 )  {
  672. X            move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 );
  673. X            printf( "%d|", row );
  674. X            move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 );
  675. X            printf( "|" );
  676. X            move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 );
  677. X            printf( "|" );
  678. X            move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 );
  679. X            printf( "|" );
  680. X        } else {
  681. X            move( row * 2 + ROW_OFFSET, COL_OFFSET - 2 );
  682. X            printf( "%d*", row );
  683. X            move( row * 2 + ROW_OFFSET + 1, COL_OFFSET - 1 );
  684. X            printf( "*" );
  685. X            move( row * 2 + ROW_OFFSET, COL_OFFSET + MAX_COLS * 3 );
  686. X            printf( "*" );
  687. X            move( row * 2 + ROW_OFFSET + 1, COL_OFFSET + MAX_COLS * 3 );
  688. X            printf( "*" );
  689. X        }
  690. X    }
  691. X    draw_current();
  692. X
  693. X    move( TABLE_ROW - 1, TABLE_COL - 1 );
  694. X    printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" );
  695. X    move( TABLE_ROW + 8 * 2 - 1, TABLE_COL - 1 );
  696. X    printf( "+-+-+-+-+-+-+-+-+-+-+-+-+" );
  697. X    for ( i = 0; i < 8; ++i ) {
  698. X        move ( TABLE_ROW + i * 2, TABLE_COL - 1 );
  699. X        printf( "|" );
  700. X        move ( TABLE_ROW + i * 2 + 1, TABLE_COL - 1 );
  701. X        printf( "+" );
  702. X        move ( TABLE_ROW + i * 2, TABLE_COL + 12 * 2 - 1);
  703. X        printf( "|" );
  704. X        move ( TABLE_ROW + i * 2 + 1, TABLE_COL +12 * 2 - 1);
  705. X        printf( "+" );
  706. X    }    
  707. X    for ( i = 0; i < TOTAL_ENTRIES; ++i )
  708. X        print_entry( i, (i == current_entry) ? true : false );
  709. X}
  710. X
  711. X
  712. X
  713. X/*
  714. X * draw_current
  715. X *    Draw the complete current entry.
  716. X */
  717. X
  718. Xvoid
  719. Xdraw_current()
  720. X{
  721. X    register int row, col;
  722. X
  723. X    printf( "\033)0" );        /* Special graphics in G1    */
  724. X    printf( "\016" );        /* Lock in G1 (SO)        */
  725. X
  726. X    for ( row = 0; row < MAX_ROWS; ++row ) {
  727. X        for ( col = 0; col < MAX_COLS; ++col ) {
  728. X            if ( display_table[row][col] ) {
  729. X                move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
  730. X                printf( "\141\141\141" );
  731. X                move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
  732. X                printf( "\141\141\141" );
  733. X            } else {
  734. X                move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
  735. X                printf( "   " );     /* erase splat    */
  736. X                move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
  737. X                printf( "   " );     /* erase splat    */
  738. X            }
  739. X        }
  740. X        pad();
  741. X    }
  742. X    printf( "\017" );        /* Lock in G0 (SI)    */
  743. X    fflush( stdout );
  744. X}
  745. X
  746. X
  747. X
  748. X/*
  749. X * highlight
  750. X *    Draw the cursor in the main display area.
  751. X */
  752. Xvoid
  753. Xhighlight( row, col, on )
  754. Xunsigned int row, col;
  755. Xbool on;
  756. X{
  757. X
  758. X    printf( "\033)0" );        /* Special graphics in G1    */
  759. X    printf( "\016" );        /* Lock in G1 (SO)        */
  760. X    if ( on ) {
  761. X        printf( "\033[7m" );    /* Reverse video cursor        */
  762. X    }
  763. X
  764. X    if ( display_table[row][col] ) {
  765. X        move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
  766. X        printf( "\141\141\141" );
  767. X        move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
  768. X        printf( "\141\141\141" );
  769. X    } else {
  770. X        move( row * 2 + ROW_OFFSET,     col * 3 + COL_OFFSET );
  771. X        printf( "   " );     /* erase splat    */
  772. X        move( row * 2 + ROW_OFFSET + 1, col * 3 + COL_OFFSET );
  773. X        printf( "   " );     /* erase splat    */
  774. X    }
  775. X    pad();
  776. X    printf( "\017" );        /* Lock in G0 (SI)    */
  777. X    printf( "\033[0m" );        /* normal video        */
  778. X    printf( "\b" );            /* Back up one spot    */
  779. X    fflush( stdout );
  780. X}
  781. X
  782. X
  783. X
  784. X/*
  785. X * Clear_screen
  786. X */
  787. Xvoid
  788. Xclear_screen()
  789. X{
  790. X    printf( "\033[H\033[J" );        /* Clear screen.    */
  791. X    fflush( stdout );
  792. X}
  793. X
  794. X
  795. X
  796. X/*
  797. X * move
  798. X */
  799. X
  800. Xmove( y, x )
  801. Xint y, x;
  802. X{
  803. X    printf( "\033[%d;%df", y, x );
  804. X}
  805. X
  806. X
  807. X
  808. X/*
  809. X * Build_entry
  810. X *    Convert the bit pattern used in the main display area into something
  811. X *    that the vt220 can digest - namely sixels...
  812. X */
  813. Xvoid
  814. Xbuild_entry( entry_no )
  815. Xunsigned int entry_no;
  816. X{
  817. X    register int row, col;
  818. X    register unsigned int mask;
  819. X
  820. X    for ( col = 0; col < 8; ++col ) {
  821. X
  822. X        /* Top set of sixels    */
  823. X
  824. X        mask = 0;
  825. X        for ( row = 5; row >= 0; --row ) {
  826. X            mask = mask << 1;
  827. X            if ( display_table[row][col] )
  828. X                mask |= 1;
  829. X        }
  830. X        font_table[entry_no][col] = mask + 077;
  831. X
  832. X        /*  Bottom set of sixels    */
  833. X
  834. X        mask = 0;
  835. X        for ( row = 9; row >= 6; --row ) {
  836. X            mask = mask << 1;
  837. X            if ( display_table[row][col] )
  838. X                mask |= 1;
  839. X        }
  840. X        font_table[entry_no][col+8] = mask + 077;
  841. X    }
  842. X        
  843. X}
  844. X
  845. X
  846. X
  847. X/*
  848. X * Extract_engry
  849. X *    convert sixel representation into an array of bits.
  850. X */
  851. X
  852. Xvoid
  853. Xextract_entry( entry_no )
  854. Xunsigned int entry_no;
  855. X{
  856. X    register int row, col;
  857. X    register unsigned int mask;
  858. X
  859. X    for ( col = 0; col < 8; ++col ) {
  860. X
  861. X        /* Top set of sixels    */
  862. X
  863. X        mask = font_table[entry_no][col];
  864. X        if ( mask >= 077 ) 
  865. X            mask -= 077;
  866. X        else
  867. X            mask = 0;        /* Bogus entry    */
  868. X
  869. X        for ( row = 0; row <= 5; ++row ) {
  870. X            display_table[row][col] = (bool)(mask & 0x0001);
  871. X            mask = mask >> 1;
  872. X        }
  873. X
  874. X        /*  Bottom set of sixels    */
  875. X
  876. X        mask = font_table[entry_no][col+8];
  877. X        if ( mask >= 077 )
  878. X            mask -= 077;
  879. X        else
  880. X            mask = 0;
  881. X
  882. X        for ( row = 6; row <= 9; ++row ) {
  883. X            display_table[row][col] = (bool)(mask & 0x0001);
  884. X            mask = mask >> 1;
  885. X        }
  886. X    }
  887. X        
  888. X}
  889. X
  890. X
  891. X
  892. X/*
  893. X * Send_entry
  894. X *    Emit the stuff used by the VT220 to load a character into the
  895. X *    DRCS.  We could, of course, send more than one entry at a time...
  896. X */
  897. X
  898. Xvoid
  899. Xsend_entry( entry_no )
  900. Xint entry_no;
  901. X{
  902. X    register char *fp    = font_table[entry_no];
  903. X
  904. X    printf( "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\", 
  905. X        entry_no,
  906. X        fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7],
  907. X        fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] );
  908. X}
  909. X
  910. X
  911. X
  912. X/*
  913. X * Print_entry
  914. X *    The terminal normally has G0 in GL.  We don't want to change
  915. X *    this, nor do we want to use GR.  Sooooo send out the necessary
  916. X *    magic for shifting in G2 temporarily for the character that we
  917. X *    want to display.
  918. X */
  919. X
  920. Xvoid
  921. Xprint_entry( entry_no, highlight )
  922. Xregister unsigned int entry_no;
  923. Xbool highlight;
  924. X{
  925. X
  926. X    register int y, x;
  927. X
  928. X    y = entry_no & 0x07;
  929. X    x = entry_no >> 3 & 0x1f;
  930. X    entry_no += 32;            /* Map up to G set    */
  931. X
  932. X    move( y * 2 + TABLE_ROW, x * 2 + TABLE_COL );
  933. X
  934. X    if ( highlight )
  935. X        printf( "\033[7m" );
  936. X
  937. X    printf( "\033* @" );        /* select DRCS into G2    */
  938. X    printf( "\033N" );        /* select single shift    */
  939. X    printf( "%c", entry_no );    /* Draw the character    */
  940. X
  941. X    if ( highlight )
  942. X        printf( "\033[0m" );
  943. X}
  944. X
  945. X
  946. X
  947. X/*
  948. X * Save_table
  949. X *    Save a font table
  950. X */
  951. X
  952. Xvoid
  953. Xsave_table( font_file )
  954. XFILE *font_file;
  955. X{
  956. X    register char *fp;
  957. X    register int i;
  958. X
  959. X    for ( i = 0; i < TOTAL_ENTRIES; ++i ) {
  960. X        fp = font_table[i];
  961. X        fprintf( font_file, "\033P1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c\033\\\n", 
  962. X            i, 
  963. X            fp[ 0], fp[ 1], fp[ 2], fp[ 3], fp[ 4], fp[ 5], fp[ 6], fp[ 7],
  964. X            fp[ 8], fp[ 9], fp[10], fp[11], fp[12], fp[13], fp[14], fp[15] );
  965. X    }
  966. X}
  967. X
  968. X
  969. X
  970. X/*
  971. X * Get_table
  972. X *    Extract font table entries from a file
  973. X */
  974. X
  975. Xvoid
  976. Xget_table( font_file )
  977. XFILE *font_file;
  978. X{
  979. X    char    s[256];
  980. X    register char    *p;
  981. X    char    *fp;
  982. X    int i;
  983. X    register int j;
  984. X
  985. X    while( fgets( s, 255, font_file ) ) {
  986. X        if ( strncmp( s, "\033P1;", 4 ) !=  0 ) 
  987. X            continue;    /* Bogus line    */
  988. X        p = &s[4];
  989. X        if ( sscanf( p, "%d", &i ) != 1 ) 
  990. X            continue;    /* Illegal entry number    */
  991. X
  992. X        if ( i <= 0 || TOTAL_ENTRIES <= i )
  993. X            continue;    /* Bogues entry    */
  994. X
  995. X        fp = font_table[i];
  996. X
  997. X        while ( *p && *p != '@' )
  998. X            ++p;        /* Skip to font definition */
  999. X        if ( ! *p++ ) 
  1000. X            continue;    /* Skip @    */
  1001. X
  1002. X        for ( j = 0; *p && *p != '\033' && j < 16; ++j, ++p ) {
  1003. X            if ( *p == '/' ) {
  1004. X                j = 8; 
  1005. X                ++p;
  1006. X            }
  1007. X            fp[j] = *p;
  1008. X        }
  1009. X        send_entry( i );
  1010. X    }
  1011. X}
  1012. X
  1013. X
  1014. X
  1015. X/*
  1016. X * Help
  1017. X *    Print out help information.
  1018. X */
  1019. Xvoid
  1020. Xhelp()
  1021. X{
  1022. X    printf( "Font editor\n\n" );
  1023. X    printf( "F6     - Pixel on\n" );
  1024. X    printf( "F7     - Pixel off\n" );
  1025. X    printf( "F13    - Clear display area\n" );
  1026. X    printf( "HELP   - This screen\n" );
  1027. X    printf( "FIND   - Update font table\n" );
  1028. X    printf( "INSERT - Insert a blank row\n" );
  1029. X    printf( "REMOVE - Remove a row\n" );
  1030. X    printf( "SELECT - Select current font table entry\n" );
  1031. X    printf( "PREV   - Move to previous font table entry\n" );
  1032. X    printf( "NEXT   - Move to next font table entry\n" );
  1033. X    printf( "^D     - Exit\n" );
  1034. X    printf( "\n\n\n\nPress any key to continue\n" );
  1035. X}
  1036. X
  1037. X
  1038. X
  1039. X/*
  1040. X * Warning
  1041. X *    Issue a warning to the regarding the current status.
  1042. X */
  1043. X
  1044. Xvoid
  1045. Xwarning( s )
  1046. Xchar *s;
  1047. X{
  1048. X    move( ERROR_ROW, ERROR_COL );
  1049. X    printf( "Warning: %s!\n", s );
  1050. X    move( ERROR_ROW+1, ERROR_COL );
  1051. X    printf( "         Reissue command to override\n" );
  1052. X}
  1053. END_OF_fontedit.c
  1054. if test 17714 -ne `wc -c <fontedit.c`; then
  1055.     echo shar: \"fontedit.c\" unpacked with wrong size!
  1056. fi
  1057. # end of overwriting check
  1058. fi
  1059. echo shar: End of shell archive.
  1060. exit 0
  1061.  
  1062.